package com.isoft.c2team3service2.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.isoft.c2team3service2.entity.SensitiveWord;
import com.isoft.c2team3service2.mapper.SensitiveWordMapper;

import com.isoft.c2team3service2.service.SensitiveWordService;
import jakarta.annotation.PostConstruct;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Service;

import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.concurrent.ConcurrentHashMap;
import java.util.stream.Collectors;

/**
 * 敏感词服务实现，使用DFA算法
 */
@Service
public class SensitiveWordServiceImpl extends ServiceImpl<SensitiveWordMapper, SensitiveWord> implements SensitiveWordService {
    private Map<String, Object> sensitiveWordMap;
    private boolean initialized = false; // 标记初始化状态
    private static final Logger log = LoggerFactory.getLogger(SensitiveWordServiceImpl.class);
    private int minWordLength = Integer.MAX_VALUE;
    private int maxWordLength = 0;

    @PostConstruct // 在Bean初始化后立即执行
    public synchronized void initSensitiveWordLibrary() {
        log.info("开始初始化敏感词库..."); // 若服务启动时无此日志，说明初始化未执行// 添加同步锁
        if (initialized) return; // 避免重复初始化

        LambdaQueryWrapper<SensitiveWord> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(SensitiveWord::getStatus, 1);
        List<SensitiveWord> sensitiveWords = list(queryWrapper);
        log.info("加载敏感词数量：{}", sensitiveWords.size());

        if (sensitiveWords.isEmpty()) {
            log.warn("敏感词库为空！");
        } else {
            sensitiveWordMap = new ConcurrentHashMap<>(); // 初始化前清空
            addSensitiveWordsToMap(sensitiveWords);
            initialized = true;
            log.info("敏感词库初始化完成，最小长度：{}，最大长度：{}", minWordLength, maxWordLength);
        }
    }

    public void refreshSensitiveWordCache() {
        initSensitiveWordLibrary();
    }

    /**
     * 将敏感词添加到DFA算法模型中
     */
    private void addSensitiveWordsToMap(List<SensitiveWord> sensitiveWords) {
        for (SensitiveWord word : sensitiveWords) {
            String sensitiveWord = word.getWord();
            // 正确：将敏感词添加到DFA模型（内存）
            addWordToDFAMap(sensitiveWord);
            // 计算敏感词长度范围（保留原逻辑）
            int length = sensitiveWord.length();
            if (length < minWordLength) {
                minWordLength = length;
            }
            if (length > maxWordLength) {
                maxWordLength = length;
            }
        }
    }

    /**
     * 构建DFA模型：将单个敏感词添加到内存中的sensitiveWordMap
     */
    private void addWordToDFAMap(String word) {
        if (word == null || word.isEmpty()) return;

        Map<String, Object> currentMap = sensitiveWordMap;
        for (int i = 0; i < word.length(); i++) {
            String charStr = String.valueOf(word.charAt(i)); // 当前字符
            // 如果当前字符已存在于map中，直接获取子map
            if (currentMap.containsKey(charStr)) {
                currentMap = (Map<String, Object>) currentMap.get(charStr);
            } else {
                // 不存在则新建子map，并添加到当前map
                Map<String, Object> newMap = new HashMap<>();
                currentMap.put(charStr, newMap);
                currentMap = newMap;
            }
            // 标记是否为敏感词的结尾（最后一个字符）
            if (i == word.length() - 1) {
                currentMap.put("isEnd", true);
            } else {
                // 非结尾字符，默认标记为false（避免遗漏）
                if (!currentMap.containsKey("isEnd")) {
                    currentMap.put("isEnd", false);
                }
            }
        }
    }

    /**
     * 实现接口方法，对文本进行敏感词过滤
     */
    public String filterText(String text) {
        if (text == null || text.isEmpty() || sensitiveWordMap == null || !initialized) {
            return text;
        }

        StringBuilder result = new StringBuilder();
        int position = 0;
        while (position < text.length()) {
            // 查找下一个可能的敏感词
            Map<String, Object> currentMap = sensitiveWordMap;
            int matchLength = 0;
            boolean isMatched = false;

            for (int i = position; i < Math.min(position + maxWordLength, text.length()); i++) {
                String charStr = String.valueOf(text.charAt(i));
                if (currentMap.containsKey(charStr)) {
                    currentMap = (Map<String, Object>) currentMap.get(charStr);
                    matchLength++;

                    // 如果找到一个完整的敏感词
                    if (Boolean.TRUE.equals(currentMap.get("isEnd"))) {
                        isMatched = true;
                        break;
                    }
                } else {
                    break; // 当前字符不在敏感词库中，跳出循环
                }
            }

            if (isMatched && matchLength >= minWordLength) {
                // 替换匹配到的敏感词为***
                result.append("*");
            } else {
                // 没有匹配到敏感词，直接添加原字符
                result.append(text.charAt(position));
            }

            position += (matchLength > 0 ? matchLength : 1);
        }

        return result.toString();
    }

    /**
     * 查找文本中从指定位置开始的敏感词
     * @return 敏感词结束位置，未找到返回-1
     */
    private int findSensitiveWord(String text, int start) {
        boolean isSensitiveWord = false;
        int length = 0;
        int end = start;

        Map<String, Object> currentMap = sensitiveWordMap;

        for (int i = start; i < text.length(); i++) {
            String word = String.valueOf(text.charAt(i));
            currentMap = (Map<String, Object>) currentMap.get(word);

            if (currentMap != null) {
                length++;
                isSensitiveWord = (boolean) currentMap.get("isEnd");
                end = i;

                // 如果找到敏感词或达到最大敏感词长度，结束查找
                if (isSensitiveWord || i == start + maxWordLength - 1) {
                    break;
                }
            } else {
                break;
            }
        }

        return isSensitiveWord ? end : -1;
    }

    /**
     * 将敏感词替换为星号
     */
    private String replaceSensitiveWord(String word) {
        return word.replaceAll(".", "*");
    }

    public boolean addSensitiveWord(String word) {
        if (word == null || word.isEmpty()) {
            return false; // 修复：添加缺失的返回值
        }

        // 更新敏感词长度范围
        if (word.length() < minWordLength) minWordLength = word.length();
        if (word.length() > maxWordLength) maxWordLength = word.length();
        if (word == null || word.isEmpty()) {
            return false;
        }

        // 检查敏感词是否已存在
        if (existsSensitiveWord(word)) {
            return false; // 已存在，不重复插入
        }

        // 保存到数据库
        SensitiveWord sensitiveWord = new SensitiveWord();
        sensitiveWord.setWord(word);
        sensitiveWord.setLevel(1); // 默认敏感级别
        sensitiveWord.setStatus(1); // 默认启用
        return save(sensitiveWord);
    }

    /**
     * 检查敏感词是否已存在
     * @param word 敏感词
     * @return 是否存在
     */
    private boolean existsSensitiveWord(String word) {
        return getOne(new QueryWrapper<SensitiveWord>().eq("word", word)) != null;
    }

    public Set<String> getAllSensitiveWords() {
        return list().stream()
                .map(SensitiveWord::getWord)
                .collect(Collectors.toSet());
    }
}